<?php
###############   COPYLEFT GPLv3 LICENSE   ###############
##
## JFX Version 0.2.9
## Website Management Software
## www.jfxcms.com
##
## Copyright 2009 GPLv3 - http://www.opensource.org/licenses/gpl-3.0.html
##
## Anthony Gallon
## oi_antz@hotmail.com
##
## Permission is hereby granted to any person having a copy of this software
## to freely use and modify as required so long as the copyright notices
## and branding remain intact.
##
## Full license details available at http://www.jfxcms.com/license
##
###############   COPYLEFT GPLv3 LICENSE   ################

class JFX_Module_Blockstyle_Handler
{
	public $controlNode = 'JFX_Module_Blockstyle_Controls';
	public $previewNode = 'JFX_Module_Blockstyle_Preview';
	public $outputNode = 'JFX_Module_Blockstyle_Output';
	public $elementsNode = 'JFX_Module_Blockstyle_Elements';
	public $linkNode = 'JFX_Module_Blockstyle_CSS';
	public $outputNodePositionTop = '-100px';
	public $outputNodePositionLeft = '-200px';
	public $previewNodePositionTop = '-100px';
	public $previewNodePositionLeft = '120px';
	public $outputNodeDefaultPositionTop = '-100px';
	public $outputNodeDefaultPositionLeft = '-200px';
	public $previewNodeDefaultPositionTop = '-100px';
	public $previewNodeDefaultPositionLeft = '120px';

	public $previewNodeState = 'closed';
	public $outputNodeState = 'closed';
	public $focusedElement = 'block';
	public $focusedWindow = 'JFX_Module_Blockstyle_Preview';

	public $ajaxUrl = '';// set this!
	public $previewUrl = '';// set this!
	public $cssUrl = '';// set this!

	public $name = '';
	public $classname = '';
	public $elements = array();
	public $privateProperties = array('elements', 'groups');
	public $runtimeProperties = array('groups');
	public $groups = array();

	public function __construct($classname){
		$this->classname = $classname;
		$this->loadElements();
	}

	public function setElement($element){
		$this->elements[get_class($element)] = $element;
	}

	public function removeElement($element){
		foreach($this->elements as $name=>$object){
			if($name==get_class($element)){
				unset($this->elements[$name]);
			}
		}
		$this->elements = array_regenerate_keys($this->elements);
	}


	public function removeWidget($widgetInstanceId){
		if($this->hasWidget($widgetInstanceId)){
			foreach($this->elements as $k=>$element){
				$this->elements[$k]->removeWidget($widgetInstanceId);
			}
		}
	}

	public function removeProperty($propertyInstanceId){
		if($this->hasProperty($propertyInstanceId)){
			foreach($this->elements as $k=>$element){
				$this->elements[$k]->removeProperty($propertyInstanceId);
			}
		}
	}


	public function setProperty($name, $value){
		if(!in_array($name, $this->privateProperties) && isset($this->$name)){
			$this->$name = $value;
		}
	}

	public function loadElements(){
		
		$dirParts = explode(DIRECTORY_SEPARATOR, rtrim(dirname(__FILE__), '/'));
		$dirParts[] = 'Element';
		$dirname = implode('/', $dirParts);
		$dh = opendir($dirname);

		$enabledElements = $this->getEnabledElements();

		while($file = readdir($dh)){
			if($file=='..' || $file=='.' || $file=='Base.php') continue;

			if(!is_dir($dirname.'/'.$file)){
				$classname = explode('.', $file);
				array_pop($classname);
				$classname = trim(implode('.', $classname));
				$classname = 'JFX_Module_Blockstyle_Element_'.ucfirst(strtolower($classname));

				if(class_exists($classname)){
					// make the object
					$newObject = new $classname;
					if(in_array($newObject->id, $enabledElements)){
						$this->getElement($newObject->id)->init();
						continue;
					}
					if(!$this->hasElement($newObject->id)){
						$this->elements[] = $newObject;
					}
				}

			}// end adding

		}// end reading directory

		return $this->elements;

	}

	public function groupElements(){
		foreach($this->elements as $k=>$element){
			if(array_key_exists($element->group, $this->groups)){
				$this->groups[$element->group][] = $element->id;
			}else{
				$this->groups[$element->group] = array($element->id);
			}
		}
		return $this->groups;
	}

	public function hasElement($id){
		$element = $this->getElement($id);
		if(!is_object($element) || false==($element instanceof JFX_Module_Blockstyle_Element_Base)){
			return false;
		}else{
			return true;
		}
	}

	public function getElement($id){
		foreach($this->elements as $k=>$element){
			if($element->id==$id){
				return $element;
			}
		}
	}

	public function getEnabledElements(){
		$retArray = array();
		foreach($this->elements as $k=>$element){
			if($element->enabled){
				$retArray[] = $element->id;
			}
		}
		return $retArray;
	}


	public function updateFromJson($handler){
		foreach(get_object_vars($handler) as $k=>$v){
			if(isset($this->$k)){
				if($k=='elements') continue;
				$this->setProperty($k, $v);
			}	
		}
		foreach($handler->elements as $classname=>$element){
			if($this->hasElement($element->id)){
				$this->getElement($element->id)->updateFromJson($element);
			}
		}
		
	}

	public function __toJson(){
		$this->prepareJson();
		$returnObject = clone $this;
		$count = 0;
		return json_encode($returnObject);
	}

	public function __toCss(){
		$returnString = '';

		foreach($this->elements as $k=>$element){
			if(!is_object($element) || false==($element instanceof JFX_Module_Blockstyle_Element_Base) || $element->enabled<=0){
				continue;
			}
			$css = $element->__toCss($this->classname);
			if(strlen(trim($css))>0){
				$returnString .= "\n".trim($css)."\n";
			}
		}

		return trim($returnString);
	}

	

	public static function getBlockCss($block, &$doneStyles){
		$cssOutput = '';
		$moduleObj = JFX::registry('JFX_Module_Blockstyle');

		if(@trim($block->getDetails('class_name'))!==''){

			$classnames = explode(' ', @trim($block->getDetails('class_name')));

			foreach($classnames as $classname){
				if(in_array($classname, $doneStyles)){
					continue;
				}else{
					$doneStyles[] = $classname;
					if(!$moduleObj->hasClassname($classname)){
						continue;
					}
					$handler = $moduleObj->getHandler($classname);
					if($handler->hasEnabledWidget()){
						$cssOutput .= "\n".trim($handler->__toCss())."\n";
					}
					unset($handler);
				}
			}
		}

		foreach($block->elements as $newBlock){
			$cssOutput .= self::getBlockCss($newBlock, $doneStyles);
		}
		return $cssOutput;
	}

	public function setPropertyProperty($propertyInstanceId, $name, $value){
		if($this->hasProperty($propertyInstanceId)){
			$this->getProperty($propertyInstanceId)->setProperty($name, $value);
		}
	}

	public function hasProperty($propertyInstanceId){
		$property = $this->getProperty($propertyInstanceId);
		if(is_object($property) && $property instanceof JFX_Module_Blockstyle_Property_Base){
			return true;
		}
		return false;
	}

	public function getProperty($propertyInstanceId){
		foreach($this->elements as $k=>$element){
			if($element->hasProperty($propertyInstanceId)){
				return $this->elements[$k]->getProperty($propertyInstanceId);
			}
		}
	}


	public function setWidgetProperty($widgetInstanceId, $name, $value){
		if($this->hasWidget($widgetInstanceId)){
			$this->getWidget($widgetInstanceId)->setProperty($name, $value);
		}
	}

	public function hasWidget($widgetInstanceId){
		$widget = $this->getWidget($widgetInstanceId);
		if(is_object($widget) && $widget instanceof JFX_Module_Blockstyle_Widget_Base){
			return true;
		}
		return false;
	}

	public function hasEnabledWidget(){
		foreach($this->elements as $k=>$element){
			if($element->hasEnabledWidget()){
				return true;
			}
		}
		return false;
	}

	public function getWidget($widgetInstanceId){
		foreach($this->elements as $k=>$element){
			if($element->hasWidget($widgetInstanceId)){
				return $this->elements[$k]->getWidget($widgetInstanceId);
			}
		}
	}
	
	public function prepareJson(){
		foreach($this->runtimeProperties as $propertyName){
			if(isset($this->$propertyName)){
				$this->propertyName = null;
			}
		}
		foreach($this->elements as $k=>$element){
			$this->elements[$k]->prepareJson();
		}
	}


}